package com.sixuan.rabbitmqconsumer;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;


/**
 * RabbitMq 入门Consumer  Hello World!
 * Created by LENOVO on 2020-7-8 15:10
 *
 * @author LENOVO
 */
public class NormalConsumer {
    private static final String rabbitMqHost = "47.97.195.191";
    private static final int rabbitMqPort = 5672;
    private static final String username = "guest";
    private static final String password = "guest";

    private static final String QUEUE_NAME = "helloWorld";


    public static void main(String[] args) throws IOException, TimeoutException {

        //通过连接工厂创建和mq的连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(rabbitMqHost);
        connectionFactory.setPort(rabbitMqPort);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        //设置虚拟机(一个虚拟机可以当做一个独立的rabbitmq应用，虚拟机之间是隔离的)
        connectionFactory.setVirtualHost("/");

        //建立新连接
        Connection connection = connectionFactory.newConnection();
        //创建会话通道，生产者和mq服务所有的通信都在channel中进行
        Channel channel = connection.createChannel();

        //声明一个队列：如果队列在mq中不存在，则创建一个
        //参数：String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
        /**
         *参数明细
         * 1.String queue 队列名称
         * 2.boolean durable 是否持久化
         * 3.boolean exclusive 是否独占连接，对接只允许在该连接中访问，如果关闭队列，则自动删除
         * 4.boolean autoDelete    是否自动删除 ，队列不在使用，则自动删除
         *                      如果将exclusive和autoDelete设置true，可用于临时队列的创建。
         * 5.Map<String, Object> arguments  参数，可以设置一个队列的扩展参数，如队列生存时间等，官方提供了许多扩展参数
         */
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);


        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            /**
             * 当接收到消息后，此方法被执行
             * @param consumerTag 消费者标签，用来标识消费者，在监听队列时设置channel.basicConsume
             * @param envelope 信封，通过envelope
             * @param properties 消息属性
             * @param body  消息内容
             * @throws IOException
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //交换机
                String exchange = envelope.getExchange();
                //消息id，mq在channel中用来表示消息的id，可用于消息已经被接收
                long deliveryTag = envelope.getDeliveryTag();
                //消息内容
                String message = new String(body, "utf-8");
                System.out.println("Received from provider : " + message);
            }
        };
        //监听消息basicConsume
        //参数：String queue, boolean autoAck, Consumer callback
        /**
         *参数明细
         * 1.String queue 队列名
         * 2.boolean autoAck 自动回复，如果设置false，需要通过编程实现回复
         * 3.Consumer callback  消费方法，当消费者受到消息所需要执行的方法
         */
        channel.basicConsume(QUEUE_NAME, true, defaultConsumer);

    }
}
